package com.myhome.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.myhome.domain.CashRechargeAuditRecord;
import com.myhome.domain.Coin;
import com.myhome.domain.Config;
import com.myhome.dto.AdminBankDto;
import com.myhome.dto.UserDto;
import com.myhome.feign.AdminFeign;
import com.myhome.feign.UserFeign;
import com.myhome.model.CashParam;
import com.myhome.service.AccountService;
import com.myhome.service.CoinService;
import com.myhome.service.ConfigService;
import com.myhome.vo.BuyCashRechargeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.myhome.mapper.CashRechargeMapper;
import com.myhome.domain.CashRecharge;
import com.myhome.service.CashRechargeService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

/**
*@Author QYiXin
* @Date 2021 10 20 09 37
**/
@Service
@Transactional
public class CashRechargeServiceImpl extends ServiceImpl<CashRechargeMapper, CashRecharge> implements CashRechargeService{
    @Autowired
    UserFeign userFeign;
    @Autowired
    AccountService accountService;
    @Autowired
    CoinService coinService;
    @Autowired
    AdminFeign adminFeign;
    @Autowired
    ConfigService configService;
    @Autowired
    Snowflake snowflake;

    @Override
    public Page<CashRecharge> getPageCashRecharge(Page<CashRecharge> page, Long coinId, Long userId, String userName, String mobile, Byte status, String numMin, String numMax, String startTime, String endTime) {
        LambdaQueryWrapper<CashRecharge> lambdaQuery = new LambdaQueryWrapper<>();
        Map<Long, UserDto> userDtoMap = null;
        if (!StringUtils.isEmpty(userId) || !StringUtils.isEmpty(userName) || !StringUtils.isEmpty(mobile)) {
            userDtoMap = userFeign.getMapUserDto(Arrays.asList(userId), userName, mobile);
            if (ObjectUtils.isEmpty(userDtoMap)) {
                return page;
            }
            lambdaQuery.in(CashRecharge::getUserId, userDtoMap.keySet());
        }
        lambdaQuery.eq(coinId!=null,CashRecharge::getCoinId, coinId)
                .eq(status!=null,CashRecharge::getStatus, status)
                .between((!StringUtils.isEmpty(startTime) && !StringUtils.isEmpty(endTime)), CashRecharge::getCreated, startTime, endTime + " 23:59:59")
                .between((!StringUtils.isEmpty(numMax) && !StringUtils.isEmpty(numMin)), CashRecharge::getNum, new BigDecimal(numMin == null ? "0" : numMin), new BigDecimal(numMax == null ? "0" : numMax));
        Page<CashRecharge> result = this.page(page, lambdaQuery);
        List<CashRecharge> records = result.getRecords();
        System.out.println("结果："+userDtoMap==null);
        if(userDtoMap==null){ // 说明前面没有使用用户的信息查询用户
            List<Long> userIds = records.stream().map(cashRecharge -> cashRecharge.getUserId()).collect(Collectors.toList());
            if (!CollectionUtil.isEmpty(userIds)) {
                userDtoMap =  userFeign.getMapUserDto(userIds,null,null) ;
            }
        }
        if (records != null) {
            for (CashRecharge record : records) {
                if (userDtoMap != null) {
                    UserDto userDto = userDtoMap.get(record.getUserId());
                    if (userDto != null) {
                        record.setUsername(userDto.getUsername());
                        record.setRealName(userDto.getRealName());
                    }
                }
            }
        }
        return result;
    }

    @Override
    public Boolean updateCashRechargeStatus(CashRechargeAuditRecord cashRechargeAuditRecord) {
        Long id = cashRechargeAuditRecord.getId();
        Long auditId = Long.valueOf(SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
        CashRecharge cashRecharge = this.getById(id);
        Boolean isOk;
        if (cashRecharge == null) {
            throw new IllegalArgumentException("不存在该充值信息记录");
        }
        if (cashRecharge.getStatus() != (byte)0) {
            throw new IllegalArgumentException("该用户已经审过过了");
        }else {
            //审核通过
            if (cashRechargeAuditRecord.getStatus() == (byte) 1) {
                accountService.cashRechargeUpdate(cashRecharge.getNum(),auditId, cashRecharge.getUserId(), cashRechargeAuditRecord.getStatus(), cashRecharge.getStep() + 1, cashRechargeAuditRecord.getRemark(),cashRecharge.getCoinId(),cashRecharge.getFee(),Long.valueOf(cashRecharge.getTradeno()));
            }
            CashRechargeAuditRecord newCashRechargeAuditRecord = new CashRechargeAuditRecord();
            newCashRechargeAuditRecord.setAuditUserId(auditId);
            newCashRechargeAuditRecord.setStatus(cashRechargeAuditRecord.getStatus());
            newCashRechargeAuditRecord.setCreated(new Date());
            newCashRechargeAuditRecord.setRemark(cashRechargeAuditRecord.getRemark());
            newCashRechargeAuditRecord.setOrderId(Long.valueOf(cashRecharge.getTradeno()));
            newCashRechargeAuditRecord.setAuditUserName(String.valueOf(auditId));
            cashRecharge.setStatus(cashRechargeAuditRecord.getStatus());
            isOk = this.updateById(cashRecharge);
        }
        return isOk;
    }

    @Override
    public Page<CashRecharge> getOneUserCashRecharge(Page<CashRecharge> page, Byte status, Long userId) {
        return this.page(page, new LambdaQueryWrapper<CashRecharge>().eq(userId != null, CashRecharge::getUserId, userId).eq(status != null, CashRecharge::getStatus, status));
    }

    @Override
    public BuyCashRechargeVo buyCashRecharge(Long userId, CashParam cashParam) {
        Coin coin = coinService.getById(cashParam.getCoinId());
        checkCashParam(cashParam);
        if (coin == null) {
            throw new IllegalArgumentException("该货币不存在");
        }
        List<AdminBankDto> adminBankDto = adminFeign.getAdminBankDto();
        if (adminBankDto == null) {
            throw new IllegalArgumentException("抱歉，不存在可用账户");
        }
        Config buyGCNRate = configService.getConfigByCode("CNY2USDT");
        BigDecimal realMum = cashParam.getMum().multiply(new BigDecimal(buyGCNRate.getValue())).setScale(2, RoundingMode.HALF_UP);
        AdminBankDto oneBank = getOndAdminBank(adminBankDto);
        CashRecharge cashRecharge = new CashRecharge();
        String remark = RandomUtil.randomNumbers(6);
        cashRecharge.setStatus((byte)0);
        cashRecharge.setBankCard(oneBank.getBankCard());
        cashRecharge.setCreated(new Date());
        cashRecharge.setCoinId(cashParam.getCoinId());
        cashRecharge.setCoinName(coin.getName());
        cashRecharge.setFee(BigDecimal.valueOf(0));
        cashRecharge.setBankName(oneBank.getBankName());
        cashRecharge.setLastTime(new Date());
        cashRecharge.setLastUpdateTime(new Date());
        cashRecharge.setMum(realMum);
        cashRecharge.setNum(cashParam.getNum());
        cashRecharge.setType("linepay");
        cashRecharge.setStep((byte) 1);
        cashRecharge.setUserId(userId);
        cashRecharge.setRemark(remark);
        cashRecharge.setTradeno(String.valueOf(snowflake.nextId()));
        boolean isSave = this.save(cashRecharge);
        if (!isSave) {
            throw new IllegalArgumentException("充值失败，请联系管理员");
        }
        BuyCashRechargeVo cashRechargeVo = new BuyCashRechargeVo();
        cashRechargeVo.setBankCard(oneBank.getBankCard());
        cashRechargeVo.setBankName(oneBank.getBankName());
        cashRechargeVo.setAmount(realMum);
        cashRechargeVo.setStatus((byte) 0);
        cashRechargeVo.setRemark(remark);
        return cashRechargeVo;
    }

    private void checkCashParam(CashParam cashParam) {
        Config config = configService.getConfigByCode("WITHDRAW_MIN_AMOUNT");
        String value = config.getValue();
        BigDecimal minCoin = new BigDecimal(value);
        BigDecimal num = cashParam.getNum();
        if (minCoin.compareTo(num) > 0) {
            throw new IllegalArgumentException("充值金额太小");
        }

    }

    private AdminBankDto getOndAdminBank(List<AdminBankDto> adminBankDto) {
        Random random = new Random();
        int size = adminBankDto.size();
        if (size == 0) {
            throw new IllegalArgumentException("不存在可用账户");
        }
        System.out.println(size);
        return adminBankDto.get(random.nextInt(size));
    }
}
